from typing import List, Dict, Any, Optional
from .base_deduper import BaseDeduper, DedupMethodRegistry
from .minhash_deduper import MinHashDeduper
from .exact_deduper import ExactDeduper
from .md5_deduper import MD5Deduper
from .simhash_deduper import SimHashDeduper


class DedupFactory:
    """
    去重工厂类，负责创建和管理不同的去重算法实例
    """
    
    @staticmethod
    def create_deduper(method_name: str, texts: List[str], **kwargs) -> BaseDeduper:
        """
        创建去重器实例
        
        Args:
            method_name: 去重方法名称
            texts: 待去重的文本列表
            **kwargs: 算法特定的参数
            
        Returns:
            去重器实例
        """
        deduper_class = DedupMethodRegistry.get_method(method_name)
        if not deduper_class:
            raise ValueError(f"未知的去重方法: {method_name}")
        
        return deduper_class(texts, **kwargs)
    
    @staticmethod
    def get_available_methods() -> List[Dict[str, Any]]:
        """
        获取所有可用的去重方法信息
        
        Returns:
            去重方法信息列表
        """
        methods = []
        for method_name in DedupMethodRegistry.list_methods():
            method_info = DedupMethodRegistry.get_method_info(method_name)
            if method_info:
                methods.append(method_info)
        return methods
    
    @staticmethod
    def get_method_info(method_name: str) -> Dict[str, Any]:
        """
        获取特定去重方法的详细信息
        
        Args:
            method_name: 去重方法名称
            
        Returns:
            去重方法详细信息
        """
        return DedupMethodRegistry.get_method_info(method_name)
    
    @staticmethod
    def validate_parameters(method_name: str, parameters: Dict[str, Any]) -> Dict[str, Any]:
        """
        验证参数并返回有效的参数集
        
        Args:
            method_name: 去重方法名称
            parameters: 用户提供的参数
            
        Returns:
            验证后的参数集
        """
        method_info = DedupMethodRegistry.get_method_info(method_name)
        if not method_info:
            raise ValueError(f"未知的去重方法: {method_name}")
        
        validated_params = {}
        method_params = method_info.get('parameters', {})
        default_params = method_info.get('default_params', {})
        
        for param_name, param_config in method_params.items():
            user_value = parameters.get(param_name)
            
            if user_value is not None:
                # 验证参数类型
                param_type = param_config.get('type')
                if param_type == 'float':
                    try:
                        validated_params[param_name] = float(user_value)
                    except (ValueError, TypeError):
                        raise ValueError(f"参数 {param_name} 必须是浮点数")
                elif param_type == 'int':
                    try:
                        validated_params[param_name] = int(user_value)
                    except (ValueError, TypeError):
                        raise ValueError(f"参数 {param_name} 必须是整数")
                elif param_type == 'bool':
                    if isinstance(user_value, str):
                        validated_params[param_name] = user_value.lower() in ('true', '1', 'yes', 'on')
                    else:
                        validated_params[param_name] = bool(user_value)
                else:
                    validated_params[param_name] = user_value
                
                # 验证参数范围
                if 'range' in param_config:
                    min_val, max_val = param_config['range']
                    if validated_params[param_name] < min_val or validated_params[param_name] > max_val:
                        raise ValueError(f"参数 {param_name} 必须在 {min_val} 到 {max_val} 之间")
                
                # 验证选项
                if 'options' in param_config:
                    if validated_params[param_name] not in param_config['options']:
                        raise ValueError(f"参数 {param_name} 必须是 {param_config['options']} 中的一个")
            else:
                # 使用默认值
                validated_params[param_name] = default_params.get(param_name)
        
        return validated_params


# 确保所有去重方法都被导入和注册
# 这里显式导入以确保注册发生
__all__ = ['DedupFactory', 'MinHashDeduper', 'ExactDeduper', 'MD5Deduper', 'SimHashDeduper']
